﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace Space_Conquest
{

    enum FogStatus
    {
        Unexplorered = 0,   // Won't render for player
        Explorered = 1,     // Renders 50% alpha map, no units
        Visible = 2         // All visible
    }

    class Player : IInput
    {

        #region Variables

        /// <summary>
        /// Declears variables with temp variable
        /// </summary>
        string _name;
        int _id;
        FogStatus[,] _fogArray;
        int _metal;
        int _fuel;
        int _electricity;
        Unit _selectedUnit;
        GameEngine _parent;
        List<Unit> _myUnits = new List<Unit>();

        #endregion

        #region Properties

        public Unit SelectedUnit
        {
            get
            {
                return _selectedUnit;
            }
            set
            {
                _selectedUnit = value;
            }

        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public int ID
        {
            get
            {
                return _id;
            }
        }

        public GameEngine Parent
        {
            get
            {
                return _parent;
            }
        }

        public int Metal
        {
            get
            {
                return _metal;
            }
            set
            {
                _metal = value;
            }
        }

        public int Fuel
        {
            get
            {
                return _fuel;
            }
            set
            {
                _fuel = value;
            }
        }

        public int Electricity
        {
            get
            {
                return _electricity;
            }
            set
            {
                _electricity = value;
            }
        }

        public List<Unit> MyUnits
        {
            get
            {
                return _myUnits;
            }
        }

        public FogStatus[,] FogArray
        {
            get
            {
                return _fogArray;
            }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Player constructor, set values to 0
        /// </summary>
        public Player(GameEngine parent, int id, string name)
        {
            _id = id;
            _parent = parent;
            Initialize(name, 400, 300, 0);
        }

        public Player(GameEngine parent, int id, string name, int metal, int fuel, int electricty)
        {
            _id = id;
            _parent = parent;
            Initialize(name, metal, fuel, electricty);
        }

        void Initialize(string name, int metal, int fuel, int electricty)
        {

            _name = name;
            _metal = metal;
            _fuel = fuel;
            _electricity = electricty;

            _selectedUnit = null;

        }

         

        #endregion

        #region IInput Members

        public bool MouseDown(MouseButtons button, int x, int y)
        {

            int tileX = x / 64;
            int tileY = y / 64;

            if (tileX < 0) tileX = 0;
            if (tileY < 0) tileY = 0;
            if (tileX >= Parent.Map.WidthInTiles - 1) tileX = Parent.Map.WidthInTiles - 1;
            if (tileY >= Parent.Map.HeightInTiles - 1) tileY = Parent.Map.HeightInTiles - 1;

            if (button == MouseButtons.Left)
            {

                SelectedUnit = null;

                if (_fogArray[tileX, tileY] == FogStatus.Visible)
                {
                    SelectedUnit = Parent.Map.GroundMap[tileX, tileY];

                    if (SelectedUnit == null)
                        SelectedUnit = Parent.Map.AirMap[tileX, tileY];
                }

                
            }
            else if (button == MouseButtons.Right &&
                SelectedUnit != null &&
                SelectedUnit.Owner == this)
            {

                Unit unitClicked = Parent.Map.GroundMap[tileX, tileY];

                if (unitClicked != null)
                {
                    if (unitClicked is ResourceUnit && SelectedUnit is Laborer)
                    {

                        ((Laborer)SelectedUnit).GatherResource((ResourceUnit)unitClicked);
                        if (this == Parent.LocalPlayer)
                        {
                            Parent.AnimationManager.DisplayAnimation(AnimationType.GatherUnit, RenderLayer.AboveGroundUnitsBelowAirUnits, new MapPoint(tileX, tileY));
                        }

                    }
                    else if (unitClicked is BuildingUnit && !((BuildingUnit)unitClicked).IsBuilt && unitClicked.Owner == this)
                    {
                        ((Laborer)SelectedUnit).BuildBuilding(((BuildingUnit)unitClicked));
                        if (this == Parent.LocalPlayer)
                        {
                            Parent.AnimationManager.DisplayAnimation(AnimationType.BuildUnit, RenderLayer.AboveGroundUnitsBelowAirUnits, new MapPoint(tileX, tileY));
                        }
                    }
                    else if (!(unitClicked is ResourceUnit) && unitClicked.Owner != this)
                    {

                        ((MovableUnit)SelectedUnit).Attack(unitClicked);
                        if (this == Parent.LocalPlayer)
                        {
                            Parent.AnimationManager.DisplayAnimation(AnimationType.AttackUnit, RenderLayer.AboveAirUnits, new MapPoint(tileX, tileY));
                        }

                    }
                }
                else
                {

                    if (SelectedUnit is MovableUnit)
                    {
                        ((MovableUnit)SelectedUnit).Move(tileX, tileY);
                        if (this == Parent.LocalPlayer)
                        {
                            Parent.AnimationManager.DisplayAnimation(AnimationType.MoveTo, RenderLayer.BelowGroundUnits, new MapPoint(tileX, tileY));
                        }
                    }

                }

            }

            return false;
        }

        public bool MouseUp(System.Windows.Forms.MouseButtons button, int x, int y)
        {
            return false;
        }

        public bool MouseMove(int x, int y)
        {
            return false;
        }

        public bool KeyDown(System.Windows.Forms.Keys key, bool shift)
        {

            if (SelectedUnit != null && SelectedUnit.Owner == this)
            {
                if (SelectedUnit is Laborer)
                {
                    switch (key)
                    {
                        case Keys.T:
                            Parent.OnScreenDisplay.BuildTownCenter();
                            break;
                        case Keys.R:
                            Parent.OnScreenDisplay.BuildTurret();
                            break;
                        case Keys.A:
                            Parent.OnScreenDisplay.BuildAirStation();
                            break;
                        case Keys.B:
                            Parent.OnScreenDisplay.BuildBarrack();
                            break;
                        case Keys.F:
                            Parent.OnScreenDisplay.BuildFactory();
                            break;
                        case Keys.P:
                            Parent.OnScreenDisplay.BuildPowerPlant();
                            break;
                    }
                }
                else if (SelectedUnit is BuildingUnit && ((BuildingUnit)SelectedUnit).IsBuilt)
                {
                    if (SelectedUnit is TownCenter)
                    {
                        switch (key)
                        {
                            case Keys.L:
                                Parent.OnScreenDisplay.CreateLaborer();
                                break;
                        }
                    }
                    else if (SelectedUnit is AirStation)
                    {
                        switch (key)
                        {
                            case Keys.L:
                                Parent.OnScreenDisplay.CreateLightShip();
                                break;
                            case Keys.B:
                                Parent.OnScreenDisplay.CreateBattleship();
                                break;
                        }
                    }
                    else if (SelectedUnit is Barrack)
                    {
                        switch (key)
                        {
                            case Keys.S:
                                Parent.OnScreenDisplay.CreateSoldier();
                                break;
                            case Keys.R:
                                Parent.OnScreenDisplay.CreateRobot();
                                break;
                        }
                    }
                    else if (SelectedUnit is Factory)
                    {
                        switch (key)
                        {
                            case Keys.J:
                                Parent.OnScreenDisplay.CreateJeep();
                                break;
                            case Keys.T:
                                Parent.OnScreenDisplay.CreateTank();
                                break;
                        }
                    }
                    else if (SelectedUnit is PowerPlant)
                    {
                        if (key == Keys.G)
                        {
                            if (((PowerPlant)SelectedUnit).IsProducingElectricity == true)
                            {
                                ((PowerPlant)SelectedUnit).IsProducingElectricity = false;
                            }
                            else
                            {
                                ((PowerPlant)SelectedUnit).IsProducingElectricity = true;
                            }
                        }
                    }
                }

            }


            return false;
        }

        public bool KeyUp(System.Windows.Forms.Keys key, bool shift)
        {
            return false;
        }

        #endregion

        #region Methods

        public void InitializeFogArray(int _xTiles,int _yTiles)
        {

            _fogArray = new FogStatus[_xTiles, _yTiles];

            for (int j = 0; j < _yTiles; j++)
            {
                for (int i = 0; i < _xTiles; i++)
                {
                    _fogArray[i, j] = FogStatus.Unexplorered;
                }
            }

        }

        public void ResetFog()
        {

            // Set all visible to Explored.
            for (int j = 0; j <= _fogArray.GetUpperBound(1); j++)
            {
                for (int i = 0; i <= _fogArray.GetUpperBound(0); i++)
                {

                    if (_fogArray[i, j] == FogStatus.Visible)
                    {
                        _fogArray[i, j] = FogStatus.Explorered;
                    }
                }
            }

            // Find new vision area
            foreach (Unit u in _myUnits)
            {
                FindUnitVision(u.X, u.Y, u.VisionRange);
            }

        }

        void FindUnitVision(int x, int y, int levelsToGo)
        {

            for (int i = x - levelsToGo; i <= x + levelsToGo; ++i)
            {

                int start = (y - levelsToGo) + Math.Abs(i - x);

                for (int j = start; j <= start + (2 * (levelsToGo - Math.Abs(i - x))); ++j)
                {
                    if (i >= 0 && j >= 0 && i <= _fogArray.GetUpperBound(0) && j <= _fogArray.GetUpperBound(1))
                    {
                        _fogArray[i, j] = FogStatus.Visible;
                    }
                }

            }

        }

        public static Color GetColor(int playerID)
        {
            switch (playerID)
            {
                case 0:
                    return Color.Red;
                case 1:
                    return Color.Blue;
                case 2:
                    return Color.Green;
                case 3:
                    return Color.Purple;
                default:
                    return Color.Black;
            }
        }

        public void PlaySound(string fileName, MapPoint playWhere)
        {

            if (_fogArray[playWhere.X, playWhere.Y] == FogStatus.Visible &&
                Parent.Map.IsWithinRenderBounds(playWhere))
            {
                Audio.PlaySound(fileName);
            }

        }

        #if DEBUG

        public void ExploreEntireMap()
        {

            for (int j = 0; j < _fogArray.GetUpperBound(1); ++j)
            {
                for(int i = 0; i < _fogArray.GetUpperBound(0); ++i)
                {
                    _fogArray[i, j] = FogStatus.Explorered;
                }
            }

        }

        #endif

        #endregion

    }
}
